package showapi

import (
	"crypto/md5"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
	"time"
)

type Showapi struct {
	Secret  string
	MainUrl string
	AppId   string
	Method  string
	Gzip    string
}

func New(secret string, mainurl string, appid string) *Showapi {
	result := Showapi{}
	result.Secret = secret
	result.MainUrl = mainurl
	result.AppId = appid
	return &result
}

func (api *Showapi) Url(appParams map[string]string) string {
	params := make(map[string]string)
	params["showapi_appid"] = api.AppId
	params["showapi_timestamp"] = time.Now().Format("20060102150405")
	params["showapi_sign_method"] = "md5"
	params["showapi_res_gzip"] = "1"

	for k, v := range appParams {
		params[k] = v
	}

	keys := []string{}
	for k, _ := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	sortResult := []string{}
	for _, key := range keys {
		sortResult = append(sortResult, key, params[key])
	}

	urlResult := []string{api.MainUrl, "?"}
	sign := fmt.Sprintf("%x", md5.Sum([]byte(strings.Join(sortResult, "")+api.Secret)))
	for _, key := range keys {
		urlResult = append(urlResult, key, "=", params[key], "&")
	}
	urlResult = append(urlResult, "showapi_sign=", sign)
	return strings.Join(urlResult, "")
}

func (api *Showapi) GetString(appParams map[string]string) (string, error) {
	url := api.Url(appParams)
	r, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer r.Body.Close()
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return "", err
	}
	return string(b), nil
}

func (api *Showapi) GetJson(appParams map[string]string, result interface{}) error {
	url := api.Url(appParams)
	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()
	return json.NewDecoder(r.Body).Decode(result)
}
